# -*- coding: UTF-8 -*-
import ujson
import utime as time
from  aliyunIoT import Device
import ota
import kv
import app_relay
import app_config
import app_uart_recv_send

mynet = None
device = None
deviceSecret = None
deviceName=None
productKey=None
productSecret=None
heartBeat=None
device_dyn_resigter_succed = False
# 定义需要升级的模块和版本号
module_name = 'default'
app_version = '1.0.1'
# 定义升级包的下载和安装路径，其中url,hash_type和hash 会通过服务端推送被保存下来

info = {
    'url': '',
    'store_path': '/data/pyamp/app.zip',
    'install_path': '/data/pyamp/',
    'length': 0,
    'hash_type': '',
    'hash': ''
}


mqtt_connect_flag=False

def get_app_version():
    global app_version
    return app_version

def get_mqtt_connect_flag():
    global mqtt_connect_flag
    return mqtt_connect_flag

 # ota 消息推送的接受函数
def on_trigger(data):
     global info
 # 保存服务端推送的ota信息
     info['url'] = data['url']
     info['length'] = data['length']
     info['module_name'] = data['module_name']
     info['version'] = data['version']
     info['hash'] = data['hash']
     info['hash_type'] = data['hash_type']
    # 开始ota 包下载
     dl_data = {}
     dl_data['url'] = info['url']
     dl_data['store_path'] = info['store_path']
     ota.download(dl_data)



 # ota 升级包下载结果回调函数
def on_download(data):
     global info
     if data >= 0:
         print('Ota download succeed')
     # 开始ota包校验
         param = {}
         param['length'] = info['length']
         param['store_path'] = info['store_path']
         param['hash_type'] = info['hash_type']
         param['hash'] = info['hash']
         ota.verify(param)

 # ota 升级包校验结果回调函数
def on_verify(data):
      global info
      print(data)
      if data >= 0 :
          print('Ota verify succeed')
          print('Start Upgrade')
     # 开始ota升级
          param = {}
          param['length'] = info['length']
          param['store_path'] = info['store_path']
          param['install_path'] = info['install_path']
          ota.upgrade(param)

 # ota 升级包结果回调函数
def on_upgrade(data):
     if data >= 0 :
        print('Ota succeed')
        #ota升完级后 重启设备
        reboot()




#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
    global mqtt_connect_flag
    mqtt_connect_flag=True
    print('***** connect lp succeed****')
    global module_name,app_version,productKey,deviceName
    data_handle = {}
    data_handle['device_handle'] = device.getDeviceHandle()

 # 初始化ota服务
    ota.init(data_handle)

 # ota 回调函数注册
    ota.on(1,on_trigger)
    ota.on(2,on_download)
    ota.on(3,on_verify)
    ota.on(4,on_upgrade)
    report_info = {
         "device_handle": data_handle['device_handle'],
         "product_key": productKey ,
         "device_name": deviceName ,
         "module_name": module_name ,
         "version": app_version
         }
 # 上报本机ota相关信息,上报版本信息返回以后程序返回，知道后台推送ota升级包，才会调用on_trigger函数
    ota.report(report_info)   
 

#当连接断开时，触发'disconnect'事件
def on_disconnect(data):
    print('linkkit is disconnected')

#当iot云端下发属性设置时，触发'props'事件
def on_props(request):
    print('clound req data is {}'.format(request))
    # clound req data is {'code': 0, 'params_len': 14, 'msg_id': 1657919022, 'params': '{"name":"HD1"}'}
    # clound req data is {'code': 0, 'params_len': 12, 'msg_id': 1652431071, 'params': '{"id":"001"}'}
    # clound req data is {'code': 0, 'params_len': 13, 'msg_id': 1792792417, 'params': '{"adcType":0}'}
    # clound req data is {'code': 0, 'params_len': 36, 'msg_id': 87002688, 'params': '{"diMode":{"diMode1":1,"diMode2":1}}'}
    # clound req data is {'code': 0, 'params_len': 38, 'msg_id': 252687440, 'params': '{"aiMode":{"aiMode1":10,"aiMode2":10}}'}
    # clound req data is {'code': 0, 'params_len': 12, 'msg_id': 431672159, 'params': '{"relay1":0}'}
    # clound req data is {'code': 0, 'params_len': 12, 'msg_id': 643669964, 'params': '{"reboot":0}'}
    # clound req data is {'code': 0, 'params_len': 16, 'msg_id': 910521246, 'params': '{"heartBeat":60}'}
    # clound req data is {'code': 0, 'params_len': 21, 'msg_id': 1140944301, 'params': '{"uploadInterval":10}'}
    # clound req data is {'code': 0, 'params_len': 89, 'msg_id': 1016037952, 'params': '{"rs232Config":{"baudRate":115200,"stopBits":1,
    #                                                                                    "enable":0,"parity":"none","dataWidth":8}}'}


    # # # #获取消息中的params数据
    params=request['params']
    # #去除字符串的''，得到字典数据
    params=eval(params)


    if "name" in params and params["name"] is not None:
        app_config.write_read_cfg(params)
        result,option=app_config.read_cfg()
        update("name",result["name"])
        # 修改设备名称
        pass
    
    if "id" in params and params["id"] is not None:
        app_config.write_read_cfg(params)
        result,option=app_config.read_cfg()
        update("id",result["id"])        

        pass
    if "heartBeat" in params and params["heartBeat"] is not None:
        app_config.write_read_cfg(params)
        result,option=app_config.read_cfg()
        update("heartBeat",result["heartBeat"])
        pass
    
    if "uploadInterval" in params and params["uploadInterval"] is not None:
        app_config.write_read_cfg(params)
        result,option=app_config.read_cfg()
        update("uploadInterval",result["uploadInterval"])        
        pass
    if "adcType" in params and params["adcType"] is not None:
        app_config.write_read_cfg(params)
        result,option=app_config.read_cfg()
        update("adcType",result["adcType"]) 
        pass

    if "diMode" in params and params["diMode"] is not None:
        if "diMode1" and "diMode2" in  params["diMode"]:
            app_config.write_read_cfg(params)
            result,option=app_config.read_cfg()
            update("diMode",{"diMode1":result["diMode1"],"diMode2":result["diMode2"]})  
            pass
    if "aiMode" in params and params["aiMode"] is not None:
        if "aiMode1" and "aiMode2" in  params["aiMode"]:
            app_config.write_read_cfg(params)
            result,option=app_config.read_cfg()
            update("aiMode",{"aiMode1":result["aiMode1"],"aiMode2":result["aiMode2"]})  
    if "subcontractInterval" in params and params["subcontractInterval"] is not None:
        print("-----",params)
        app_config.write_read_cfg(params)
        result,option=app_config.read_cfg()
        update("subcontractInterval",result["subcontractInterval"])              

    if "relay1" in params and params["relay1"] is not None:
        if params["relay1"]==0:
            app_relay.relay_ctl(1,0)
        elif params["relay1"]==1:
            app_relay.relay_ctl(1,1)
        update("relay1",app_relay.get_relay_state(1))     
    if "relay2" in params and params["relay2"] is not None:
        if params["relay2"]==0:
            app_relay.relay_ctl(2,0)
        elif params["relay2"]==1:
            app_relay.relay_ctl(2,1)    
        update("relay2",app_relay.get_relay_state(2))    
    if "rs232Config" in params and params["rs232Config"] is not None:
        app_config.write_read_cfg(params)
        app_config.write_read_board(params)
        reboot()
    if "rs485Config" in params and params["rs485Config"] is not None:
        app_config.write_read_cfg(params)
        app_config.write_read_board(params)
        reboot()          
    if "reboot" in params and params["reboot"] is not None:

        if params["reboot"]==1:
            reboot()

    if "485SendData" in params and params["485SendData"] is not None:
        writeBuf= params["485SendData"]
        app_uart_recv_send.rs485_data_from_cloud(writeBuf)
        update("485SendData",params["485SendData"])
        pass        
    if "232SendData" in params and params["232SendData"] is not None:
        writeBuf= params["232SendData"]
        app_uart_recv_send.rs232_data_from_cloud(writeBuf)
        update("232SendData",params["232SendData"])        
        pass   

    print('----------------------------')    


#当iot云端调用设备service时，触发'service'事件
def on_service(id,request):
    print('clound req id  is {} , req is {}'.format(id,request))


#当设备跟iot平台通信过程中遇到错误时，触发'error'事件
def on_error(err):
    print('err msg is {} '.format(err))



#动态注册回调函数
def on_dynreg_cb(data):
    global deviceSecret,device_dyn_resigter_succed
    deviceSecret = data
    device_dyn_resigter_succed = True

# 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
    global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed
    key = '_amp_customer_devicesecret'
    deviceSecretdict = kv.get(key)
    if isinstance(deviceSecretdict,str):    
        deviceSecret = deviceSecretdict 

    if deviceSecretdict is None or deviceSecret is None:
        key_info = {
            'productKey': productKey  ,
            'productSecret': productSecret ,
            'deviceName': deviceName
            }
        # 动态注册一个设备，获取设备的deviceSecret
        #下面的if防止多次注册，当前若是注册过一次了，重启设备再次注册就会卡住，
        if not device_dyn_resigter_succed:
            device.register(key_info,on_dynreg_cb)   



def aliyun_login(device_name,product_key,product_secret,heart_beat,area):
    global device,deviceName,productKey,productSecret,heartBeat,region
    deviceName=device_name
    productKey=product_key
    productSecret=product_secret
    heartBeat=heart_beat
    region=area
    #初始化物联网平台Device类，获取device实例
    device = Device()
    if deviceName is not None and len(deviceName) > 0 :
     #动态注册一个设备
        dyn_register_device(productKey,productSecret,deviceName)
    else:
        print("please input params of dynamic register")
        return -1
    while deviceSecret is None:
        time.sleep(0.2)
    print('dynamic register successfully:' + deviceSecret)

    key_info = {
        'region' : region ,
        'productKey': productKey ,
        'deviceName': deviceName ,
        'deviceSecret': deviceSecret ,
        'keepaliveSec': heartBeat,
        }
    #打印设备信息
    print(key_info)

    #device.ON_CONNECT 是事件，on_connect是事件处理函数/回调函数
    device.on(device.ON_CONNECT,on_connect)
    device.on(device.ON_DISCONNECT,on_disconnect)
    device.on(device.ON_PROPS,on_props)
    device.on(device.ON_SERVICE,on_service)
    device.on(device.ON_ERROR,on_error)
    device.connect(key_info)
    


def update(key,value):
    global device
    post_data_str=ujson.dumps({key:value})
    data={
        "params":post_data_str
    }
    time.sleep_ms(100)
    print("----------------",data)
    device.postProps(data)



 

 
